package net.sharpf2.api.interfaces;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sharpf2.api.Globals;
import net.sharpf2.api.Methods;
import net.sharpf2.sfcore.client.MenuNode;

/**
 *
 * @author Rick van Biljouw
 */
public class Menu {

    /**
     * Calls the Actions class.
     * @return Actions
     */
    public static Actions getActions() {
        return new Actions();
    }

    /**
     * Gets the menu data.
     * @return String array of every menu action.
     */
    private static String[] getMenuData() {
        ArrayList<String> menuStrings = new ArrayList<String>();
        MenuNode mn = Globals.CLIENT.getMenuNodeList().getFirst();
        int idx = 0;
        for (MenuNode n1 = mn.getPrev(); idx < Globals.CLIENT.getMenuOptionCount(); n1 = n1.getPrev()) {
            if (n1 != null && n1.getObject() != null) {
                menuStrings.add(n1.getAction());
                idx++;
            }
        }
        return menuStrings.toArray(new String[menuStrings.size()]);
    }

    /**
     * Gets the menu index of the specified action string.
     * @param   regexString Action.
     * @return  Menu index.
     */
    private static int getMenuIndex(String regexString) {
        Pattern regex = Pattern.compile(regexString, Pattern.CASE_INSENSITIVE
                | Pattern.UNICODE_CASE);
        String[] menu = getMenuData();
        int index = -1;
        for (int i = 0; i < menu.length; i++) {
            Matcher regexMatcher = regex.matcher(menu[i]);
            if (regexMatcher.find()) {
                index = i + 1;
                break;
            }
        }
        return index;
    }

    /**
     * Waits a maximum of 1200 ms for a specified option.
     * @param   text    Action name.
     * @return  True if option is available within 1200 ms, otherwise false.
     */
    private static boolean waitForOption(String text) {
        int tries = 0;
        while (getMenuIndex(text) == -1 && tries++ < 5 && !Thread.currentThread().isInterrupted()) {
            Methods.sleep(300);
        }
        return getMenuIndex(text) != -1;
    }

    /**
     * Returns the top menu item
     * @return First menu action name.
     */
    public static String getUptext() {
        return getMenuData()[0];
    }

    /**
     * Check if menu contains a specific option
     * @param   option  Option name to check for.
     * @return  True if action contains specified text.
     */
    public static boolean contains(String option) {
        return getMenuIndex(option) != -1;
    }

    public static class Actions {

        /**
         * Clicks in the menu
         * @param option Action name.
         */
        public void click(String option) {
            if (waitForOption(option)) {
                int index = getMenuIndex(option);

                if (index == 1) {
                    Globals.CONTROLLER.getMouse().click(true);
                } else if (index != -1) {
                    Globals.CONTROLLER.getMouse().click(false);
                    Globals.CONTROLLER.getMouse().move(Globals.CLIENT.getMenuX() + (Globals.CLIENT.getMenuWidth() / 2), (Globals.CLIENT.getMenuY() + 14) + (15 * index));
                    Globals.CONTROLLER.getMouse().click(true);
                }
            }
        }
    }
}